{(function (window){
    function Promise(excutor){
        var _this = this
        this.status = "pending"
        this.data = undefined 
        this.callbacks = []

        function resolve(result){
            if(_this.status !== "pending"){
                return
            }
            _this.status = "fulfilled"
            _this.data = result
            if(_this.callbacks.length > 0){
                _this.callbacks.forEach(function(item){
                    item.fnResolved(result)
                })
            }
        }

        function reject(result){
            if(_this.status !== "pending"){
                return
            }
            _this.status = "rejected"
            _this.data = result
            if(_this.callbacks.length > 0){
                _this.callbacks.forEach(function(item){
                    item.fnRejected(result)
                })
            }
        }

        try{
            excutor(resolve,reject)
        }catch(err){
            reject(err)
        }

    }
    Promise.prototype.then = function (fnResolved,fnRejected){
        var _this = this
        return new Promise((resolve,reject)=>{
            function tryCatch(cb){
                setTimeout(function (){
                    try{
                        var res = cb(_this.data)
                        if(res instanceof Promise){
                            res.then(resolve,reject)
                        }else{
                            resolve(res)
                        }
                    }catch(err){
                        var res = fnRejected(_this.data)
                    }
                })
            }
            if(_this.status === "fulfilled"){
                tryCatch(fnResolved)
            } else if(_this.status === "rejected"){
                tryCatch(fnRejected)
            } else{
                _this.callbacks.push({
                    "fnResolved": function (){
                        tryCatch(fnResolved)
                    },
                    "fnRejected": function (){
                        tryCatch(fnRejected)
                    }
                })
            }
        })
    }

    Promise.prototype.catch = function (catchCallback){
        return this.then(null,catchCallback)
    }

    Promise.resolve = function (res){
        if(res instanceof Promise){
            return res
        } else {
            return new Promise((resolve,reject)=>{
                resolve(res)
            })
        }
    }

    Promise.reject = function (res){
        if(res instanceof Promise){
            return res
        } else {
            return new Promise((resolve,reject)=>{
                reject(res)
            })
        }
    }

    Promise.all = function (arr){
        return new Promise((resolve,reject)=>{
            var results = []
            var count = 0
            arr.forEach(function (item,index){
                item.then(
                    function (res){
                    count++
                    results[index] = res
                    if(count === arr.length){
                        resolve(results)
                    }
                    },
                    function (res){
                        reject(res)
                    }
                )
            })
        })
    }

    Promise.race = function (arr){
        return new Promise((resolve,reject)=>{
            arr.forEach(function (item){
                item.then(
                    function (res){
                        resolve(res)
                    },
                    function (res){
                        reject(res)
                    }
                )
            })
        })
    }

    window.Promise = Promise
})(window)}